package com.xxxx.crm.service;



import com.xxxx.crm.base.BaseService;
import com.xxxx.crm.dao.UserMapper;
import com.xxxx.crm.dao.UserRoleMapper;
import com.xxxx.crm.model.UserModel;
import com.xxxx.crm.utils.AssertUtil;
import com.xxxx.crm.utils.Md5Util;
import com.xxxx.crm.utils.PhoneUtil;
import com.xxxx.crm.utils.UserIDBase64;
import com.xxxx.crm.vo.User;
import com.xxxx.crm.vo.UserRole;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;


/**
 * @Author:王亚栋
 * @Date:2021/10/23 18:12
 * @Version:1.0
 */
@Service
public class UserService extends BaseService<User,Integer> {


    @Autowired
    private UserMapper userMapper;
    @Autowired
    private UserRoleMapper userRoleMapper;

    /**
     * 用户登录
     * @param userName
     * @param password
     */
    public UserModel userLogin(String userName, String password){
        //参数判断，判断用户姓名，密码非空
        checkLoginParams(userName,password);
        //调用dao层，通过用户名查询用户信息
        User user = userMapper.queryUserByName(userName);
        //判断用户是否为空
        AssertUtil.isTrue(user == null,"用户姓名不正确");
        //判断密码是否正确，比较客户端传递的用户密码与数据库中的用户密码是否一致
        checkPassword(password,user.getUserPwd());
        //返回构建用户对象
        return buildUserInfo(user);

    }

    /**
     * 参数判断
     * @param userName
     * @param password
     */
    private void checkLoginParams(String userName, String password) {

        //用户名参数
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户名不能为空!");
        //密码参数
        AssertUtil.isTrue(StringUtils.isBlank(password),"用户密码不能为空！");

    }

    /**
     * 校验输入的密码和用户的密码是否一致
     * @param password
     * @param userPwd
     */
    private void checkPassword(String password, String userPwd) {

        //将输入的用户密码进行加密
       password = Md5Util.encode(password);
       //判断
        AssertUtil.isTrue(!password.equals(userPwd),"用户密码不正确！");

    }

    /**
     * 构建用户对象
     * @param user
     * @return
     */
    private UserModel buildUserInfo(User user) {

        UserModel userModel = new UserModel();

        //将UserId加密
        userModel.setUserIdStr(UserIDBase64.encoderUserID(user.getId()));

        userModel.setUserName(user.getUserName());

        userModel.setTrueName(user.getTrueName());

        return userModel;
    }

    /**
     * 修改用户密码
     * @param userId
     * @param oldPwd
     * @param newPwd
     * @param repeatPwd
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updatePassword(Integer userId,String oldPwd,String newPwd,String repeatPwd){

        //通过用户Id查询到用户信息
        User user = userMapper.selectByPrimaryKey(userId);
        //判断用户记录是否存在
        AssertUtil.isTrue(user == null,"待更新对象不存在！");
        //参数校验
        checkPasswordParams(user,oldPwd,newPwd,repeatPwd);
        //设置用户新密码
        user.setUserPwd(Md5Util.encode(newPwd));
        //更新用户信息
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) < 1,"修改密码失败！");
    }

    /**
     * 修改密码的参数校验
     * @param user
     * @param oldPwd
     * @param newPwd
     * @param repeatPwd
     */
    private void checkPasswordParams(User user, String oldPwd, String newPwd, String repeatPwd) {

        //判断原始密码
        AssertUtil.isTrue(StringUtils.isBlank(oldPwd),"原始密码不能为空！");
        //判断输入的原始密码和数据库的密码是否一致
        AssertUtil.isTrue(user.getUserPwd().equals(Md5Util.encode(oldPwd)),"输入的原始密码不正确！");
        //新密码不能为空
        AssertUtil.isTrue(StringUtils.isBlank(newPwd),"新密码不能为空！");
        //判断新密码是否与用户的旧密码是否一致
        AssertUtil.isTrue(oldPwd.equals(newPwd),"新密码不能与上次的就密码一致！");
        //确认密码不能为空
        AssertUtil.isTrue(StringUtils.isBlank(repeatPwd),"确认密码不能为空！");
        //确认密码与新密码是否一致
        AssertUtil.isTrue(!newPwd.equals(repeatPwd),"确认密码与新密码不一致！");


    }


    /**
     * 查询所有的销售人员
     * @return
     */
    public List<Map<String,Object>> queryAllSales(){

        return userMapper.queryAllSales();
    }

    /**
     * 添加用户操作
     * @param user
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void addUser(User user){

        /**
         * 1.参数校验
         */
        checkUserParams(user.getUserName(),user.getEmail(),user.getPhone());

        //2.设置默认值
        user.setIsValid(1);

        user.setCreateDate(new Date());

        user.setUpdateDate(new Date());

        //3.设置默认密码
        user.setUserPwd(Md5Util.encode("123456"));

        //4.执行添加方法
        AssertUtil.isTrue(userMapper.insertSelective(user) != 1,"用户记录添加失败！");

        /**
         * 用户角色关联
         *      添加操作
         *      原始角色不存在
         *          1.不添加新的角色记录   不操作用户角色表
         *          2.添加新的角色记录      给指定用户设定相关的角色记录
         *
         *      更新操作
         *          原始角色不存在
         *          1.不添加新的角色记录   不操作用户角色表
         *          2.添加新的角色记录      给指定用户设定相关的角色记录
         *          原始角色存在
         *          1.添加新的角色信息      判断已有的角色记录不添加，添加没有的角色记录
         *          2.清空所有的角色记录     删除用户绑定角色记录
         *          3.移除部分角色记录      删除不存在的角色记录，存在的角色记录保留
         *          4.移除部分角色，添加新的角色记录   删除不存在的角色记录，存在的角色记录保留，添加新的角色
         *
         *          如何进行角色分配？
         *              判断用户对应的角色记录存在，先将原有的角色记录删除，再添加新的角色记录
         *
         *          删除操作
         *              删除指定用户的角色记录
         *
         */
        relationUserRole(user.getId(),user.getRoleIds());

    }

    /**
     *
     * @param userId   用户id
     * @param roleIds  角色id
     */
    private void relationUserRole(Integer userId, String roleIds)   {

        //通过用户ID查询角色记录
        Integer count = userRoleMapper.countUserRoleByUserId(userId);
        //判断角色记录是否存在
        if (count > 0){

            //如果角色记录存在，则删除该用户对应的角色记录
            AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,"用户角色分配失败！");
        }

        //判断角色ID是否存在，如果存在，则添加该用户对应的角色记录
        if (StringUtils.isNotBlank(roleIds)) {
            //将用户角色数据设置到集合中，执行批量添加
            List<UserRole> userRoleList = new ArrayList<>();
            //将角色ID字符串转换成数组
            String[] roleIdsArray = roleIds.split(",");
            //遍历数组，得到对应的用户角色对象，并设置到集合中
            for (String roleId : roleIdsArray){

                UserRole userRole = new UserRole();

                userRole.setRoleId(Integer.parseInt(roleId));
                userRole.setUserId(userId);
                userRole.setCreateDate(new Date());
                userRole.setUpdateDate(new Date());
                //设置到集合中
                userRoleList.add(userRole);
            }
            //批量添加用户角色记录
            AssertUtil.isTrue(userRoleMapper.insertBatch(userRoleList) != userRoleList.size(),"用户角色分配失败！");
        }
    }

    /**
     * 参数校验
     * @param userName
     * @param email
     * @param phone
     */
    private void checkUserParams(String userName, String email, String phone) {

        //用户名参数
        AssertUtil.isTrue(StringUtils.isBlank(userName),"用户名不能为空！");

        //查询用户名是否存在
        User tempUser = userMapper.queryUserByName(userName);

        AssertUtil.isTrue(null != tempUser,"该用户已存在，请重新输入用户名！");

        AssertUtil.isTrue(StringUtils.isBlank(email),"邮箱不能为空！");

        AssertUtil.isTrue(StringUtils.isBlank(phone),"手机号不能为空！");

        AssertUtil.isTrue(!PhoneUtil.isMobile(phone),"手机号格式不正确！");

    }

    /**
     * 用户更新操作
     * @param user
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void updateUser(User user){

        //判断ID是否为空
        AssertUtil.isTrue(null == user.getId(),"待更新记录不存在！");

        //通过id查询数据
        User tempUser = userMapper.selectByPrimaryKey(user.getId());

        AssertUtil.isTrue(null == tempUser,"待更新记录不存在！");

        //2.参数校验
        checkUserParams(user.getUserName(),user.getEmail(),user.getPhone());

        //3.设置默认值
        user.setUpdateDate(new Date());

        //4.执行更新操作
        AssertUtil.isTrue(userMapper.updateByPrimaryKeySelective(user) != 1,"更新记录失败！");


    }

    /**
     * 删除用户操作
     * @param ids
     */
    @Transactional(propagation = Propagation.REQUIRED)
    public void deleteByIds(Integer[] ids) {

        //判断ids是否为空，长度是否为空
        AssertUtil.isTrue(ids == null || ids.length == 0,"被删除记录不存在！");
        //执行删除操作
        Integer deleteResult = userMapper.deleteBatch(ids);

        AssertUtil.isTrue(deleteResult != ids.length,"用户删除失败！");

        //遍历用户ID的数组
        for (Integer userId : ids) {

            //通过用户ID查询对应的用户角色记录
            Integer count = userRoleMapper.countUserRoleByUserId(userId);

            //判断用户角色记录是否存在
            if (count > 0){
                //通过用户ID删除对应的用户角色记录
                AssertUtil.isTrue(userRoleMapper.deleteUserRoleByUserId(userId) != count,"删除用户失败！");
            }

        }
    }


}
